#include "platform.h"
#include "SoftI2C.h"
#include "SoftUart.h"
#include "filter.h"

// 指定以下代码的优化规则
#pragma GCC push_options
#pragma GCC optimize ("O0")


uint8_t rxbuf[2];

#define OVER_MAX  2
#define BUF_SIZE  16

I2C_t LM75 ;
Kalman_t kfp ;

int16_t temp ; 
volatile int16_t temp_oversamp ; 




int32_t tempbuf [BUF_SIZE] = {0} ;
int16_t Temp_Oversampling(int16_t x) ;
int16_t GetTemp() ;
int16_t FilterMedian(int16_t* pData,int16_t nSize) ;



void main()
{
    P_TXD = 1 ;
    *I2C_BASEADDR = 0xf ; // 仿真时需要
    SoftI2C_Init(&LM75,I2C_BASEADDR ,     I2C0_PIN_SCL   ,I2C0_PIN_SDA , 10) ;
    TxSend('S') ;TxSend('S') ;
    TxSend('\r') ;TxSend('\n') ;
    KalmanInt_Init(&kfp); 
	while(1){
        // if (SoftI2C_LM75_Read(&LM75, 0x90, 0x00, rxbuf) == 1)
        // {
        //     temp = (rxbuf[0]<<8)| rxbuf[1] ;
        //     temp = temp >> 5 ;
        //     temp_oversamp = Temp_Oversampling(temp) ;
        //     TxInt16(temp_oversamp) ;
        //     TxStr("\r\n") ;

        // }
        // else
        // {
        //     TxStr("read error\r\n");
        //     LED =~LED ;
        // }
        temp =GetTemp();
        TxInt16(temp) ;
        TxStr("\r\n") ;
        Serv_Delayms(1000) ;
    }
	return ;
}



int16_t Temp_Oversampling(const int16_t x) {
    volatile int32_t sum = 0 ;
    int32_t val = x;
    for(uint8_t i=1;i< BUF_SIZE ; i++) {
        sum += tempbuf[i] ;
        tempbuf[i] = tempbuf[i-1] ;
    }
    tempbuf[0]  = val ;
    sum += val ;
    sum = sum >> 2 ;

    return (int16_t)sum;
}

int16_t GetTemp() {
    int16_t mytemp[8] ;
    int32_t sum = 0 ;
    for(uint8_t i=0;i<8;i++) {
        SoftI2C_LM75_Read(&LM75, 0x90, 0x00, rxbuf)  ;
        mytemp[i] = (rxbuf[0]<<8)| rxbuf[1] ;
        mytemp[i] = mytemp[i]>>5;
        sum += mytemp[i] ;
        Serv_Delayms(10) ;
    }
    
    sum /= 8 ;
    // sum = Temp_Oversampling(sum) ;
    // sum = FilterMedian(mytemp,8) ;
    return (int16_t)sum ;
    
}

/**
*  中位值平均滤波
* @param pData:没有滤波的数据 
* @param nSize:数据大小 
* @return:滤波数值
*/
int16_t FilterMedian(int16_t* pData,int16_t nSize)
{
    int16_t max,min;
    int16_t sum;
    if(nSize>2)
    {
        max = pData[0];
        min = max;
        sum = 0;
        for(int16_t i=0;i<nSize;i++)
        {
            sum += pData[i];            
            if(pData[i]>max)
            {
                max = pData[i];   //一个循环之后max就是最大的值
            }

            if(pData[i]<min)
            {
                min = pData[i];   //一个循环之后min就是最小的值
            }
        }

        sum = sum-max-min;       //去掉最大的值和最小的值
        return sum/(nSize-2); //对N-2个数求平均值          
    }

    return 0;
}

#pragma GCC pop_options  // 结束不优化的代码
